package uk.me.dewi.appenin.android;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import uk.me.dewi.appenin.android.dao.PersonDao;
import uk.me.dewi.appenin.android.dao.PlaceDao;
import uk.me.dewi.appenin.android.dao.db.sqlite.PlaceSqliteDao;
import uk.me.dewi.appenin.android.dao.rest.xml.PlaceXmlRestDao;
import uk.me.dewi.appenin.android.entity.Place;
import uk.me.dewi.util.DataAccessException;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo;

import com.google.android.maps.GeoPoint;

public class Appenin extends ListActivity {
    private static final int ACTIVITY_CREATE=0;
    private static final int ACTIVITY_EDIT=1;
    private static final int ACTIVITY_VIEW=2;
    
    private static final int INSERT_ID = Menu.FIRST;
    private static final int DELETE_ID = Menu.FIRST + 1;
    
    static final int DIALOG_EXCEPTION_ID = 0;
    
    public static final String PREFS_NAME = "AppeninPrefs";
    public static final String PREF_BASE_URL = "baseUrl";
    
    public static final String DEFAULT_BASE_URL = "http://10.0.2.2:8080/api"; // localhost

//  public static final String DEFAULT_BASE_URL = "http://appenin.appspot.com";
//  public static final String DEFAULT_BASE_URL = "http://appenin.appspot.com";
//  public static final String DEFAULT_BASE_URL = "http://10.0.2.2:8081/api"; // localhost proxy
    
    
//    private PlaceSqliteDao mDbHelper;
    private Location mCurrentLocation;
    
    private PlaceDao mPlaceDao;
    private PersonDao mPersonDao;
    
    private String mBaseUrl;
    
    private SharedPreferences mSettings;
    
    private String mErrorMessage;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.place_list);
        
        mSettings = getSharedPreferences(PREFS_NAME, 0);
        mBaseUrl = mSettings.getString(PREF_BASE_URL, DEFAULT_BASE_URL);

//        mDbHelper = new PlaceSqliteDao(this);
//        mDbHelper.open();
        
        mPlaceDao = new PlaceXmlRestDao(mBaseUrl); 
        
        fillDataFromRest();
        registerForContextMenu(getListView());
    }
    
    @Override
    protected void onStop(){
       super.onStop();
    
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putString("baseUrl", mBaseUrl);

      editor.commit();
      
//      mDbHelper.close();
    }

    
//    private void fillDataFromSql() {
//        Cursor cursor = mDbHelper.fetchAllPlaces();
//        startManagingCursor(cursor);
//        
//        // Create an array to specify the fields we want to display in the list (only NAME)
//        String[] from = new String[]{PlaceSqliteDao.KEY_NAME};
//        
//        // and an array of the fields we want to bind those fields to (in this case just text1)
//        int[] to = new int[]{R.id.text1};
//        
//        // Now create a simple cursor adapter and set it to display
//        SimpleCursorAdapter places = 
//                new SimpleCursorAdapter(this, R.layout.place_row, cursor, from, to);
//        setListAdapter(places);
//    }
    
    private void fillDataFromRest(){
        List<Place> places;
        try {
            places = mPlaceDao.getNearbyPlaces(new GeoPoint(1,1), 2);
            setListAdapter(new ArrayAdapter<Place>(
                    this,
                    R.layout.place_row,
                    places));
        } catch (DataAccessException e) {
            reportException("Failed to load nearby places", e);
        }
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, INSERT_ID, 0, R.string.menu_insert_place);
        return true;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch(item.getItemId()) {
        case INSERT_ID:
            createPlace();
            return true;
        }
       
        return super.onMenuItemSelected(featureId, item);
    }
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, DELETE_ID, 0, R.string.menu_delete_place);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch(item.getItemId()) {
        case DELETE_ID:
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
//            mDbHelper.deletePlace(info.id);
            fillDataFromRest();
            return true;
        }
        return super.onContextItemSelected(item);
    }
    
    private void createPlace() {
        Intent i = new Intent(this, PlaceEdit.class);
        startActivityForResult(i, ACTIVITY_CREATE);
    }
    
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Intent i = new Intent(this, PlaceView.class);
        i.putExtra(PlaceSqliteDao.KEY_ROWID, id);
        startActivityForResult(i, ACTIVITY_VIEW);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, 
                                    Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        fillDataFromRest();
    }
    
    private void updateWithNewLocation(Location location) {
        // Update your current location
        mCurrentLocation = location;

        // Geocode your current location to find an address.
        String latLongString = "";
        String addressString = "No address found";

        if (location != null) {
          double lat = location.getLatitude();
          double lng = location.getLongitude();
          latLongString = "Lat:" + lat + "\nLong:" + lng;

          Geocoder gc = new Geocoder(this, Locale.getDefault());
          try {
            List<Address> addresses = gc.getFromLocation(lat, lng, 1);
            StringBuilder sb = new StringBuilder();
            if (addresses.size() > 0) {
              Address address = addresses.get(0);

              sb.append(address.getLocality()).append("\n");
              sb.append(address.getCountryName());
            }

            addressString = sb.toString();
          } catch (IOException e) {}
        } else {
          latLongString = "No location found";
        }

        // Update the TextView to show your current address.
        TextView myLocationText = (TextView)findViewById(R.id.description);
        myLocationText.setText("Your Current Position is:\n" + latLongString + "\n" + addressString);
      }
    
    protected Dialog onCreateDialog(int id) {
        Dialog dialog;
        switch(id) {
        case DIALOG_EXCEPTION_ID:
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("Error: "+mErrorMessage)
                   .setCancelable(false)
                   .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                           mErrorMessage = null;
                           dialog.dismiss();
                       }
                   });
            dialog = builder.create();
            break;
        default:
            dialog = null;
        }
        return dialog;
    }
    
    private void reportException(String message, Throwable e){
        Log.e("PlaceEdit", message, e);
        
        mErrorMessage = message;
        showDialog(DIALOG_EXCEPTION_ID);
    }
}
